package com.ltu.util.security;


import com.alibaba.fastjson.JSONObject;
import com.ltu.util.common.StrUtils;
import com.ltu.util.exception.ApiException;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

//import Java.security.SecureRandom;

/**
 * @Description:  3DES加解密工具
 * @author: 若尘  
 * @date 2019年8月21日 下午2:32:26
 * @version V1.0
 */
@Slf4j
public class Chinaums3DesUtil {
	public static final String accesserId="QD015840";
	private static final String key= "udik876ehjde32dU61edsxsf";
	
	private static Cipher   cipher;
	static{
		try {
			cipher=Cipher.getInstance("DESede");
		} catch (NoSuchAlgorithmException e) {

			e.printStackTrace();
		} catch (NoSuchPaddingException e) {

			e.printStackTrace();
		}
	}

	public static String encrypt3DES(String data){
		log.info("待加密的数据："+data);
		String enJsonData="";
		byte[] enByte=null;
		try {
			SecretKey k=new SecretKeySpec(build3DesKey(key), "DESede");		  
			cipher.init(Cipher.ENCRYPT_MODE, k);
			enByte= cipher.doFinal(data.getBytes("utf-8"));
			 enJsonData=	StrUtils.byteToString(enByte);
		} catch (InvalidKeyException e) {

			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {

			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {

			e.printStackTrace();
		} catch (BadPaddingException e) {

			e.printStackTrace();
		} 
		log.info("加密后的数据："+enJsonData);
		return enJsonData;
	}
	
	/**
	 * @date 2019年8月21日
	 * @author 若尘
	 * @Description  若解密失败检查字符串是不是十六进制的
	 */
	public static String decrypt3DES(String encryptData){
		log.info("待解密的数据："+encryptData);
		String deJsonData="";	
		try {
			SecretKey k=new SecretKeySpec(build3DesKey(key), "DESede");
			cipher.init(Cipher.DECRYPT_MODE, k );
			byte[] deByte= cipher.doFinal(StrUtils.HexString2Bytes(encryptData));
			deJsonData= new String(deByte,"utf-8");
		} catch (InvalidKeyException e) {

			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {

			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {

			e.printStackTrace();
		} catch (BadPaddingException e) {

			e.printStackTrace();
		} 
		log.info("解密后的数据："+deJsonData);
		return deJsonData;
		
	}

	
	
	 /*
	      * 根据字符串生成密钥字节数组 
	      * @param keyStr 密钥字符串
	      * @return 
	      * @throws UnsupportedEncodingException
	      */
	     public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException{
	         byte[] key = new byte[24];    //声明一个24位的字节数组，默认里面都是0
	         byte[] temp = keyStr.getBytes("UTF-8");    //将字符串转成字节数组
	         /*
	          * 执行数组拷贝
	          * System.arraycopy(源数组，从源数组哪里开始拷贝，目标数组，拷贝多少位)
	          */
	         if(key.length > temp.length){
	             //如果temp不够24位，则拷贝temp数组整个长度的内容到key数组中
	             System.arraycopy(temp, 0, key, 0, temp.length);
	         }else{
	             //如果temp大于24位，则拷贝temp数组24个长度的内容到key数组中
	             System.arraycopy(temp, 0, key, 0, key.length);
	         }
	         return key;
	     } 
	     
	    
	  public static String chinaumsSign(String jsonData){
		  log.info("待签名的数据："+jsonData);
			MessageDigest md;
			try {
				md = MessageDigest.getInstance("SHA-256");
				md.reset();
				md.update(jsonData.getBytes("utf-8"));	
			String sign=	StrUtils.byteToString(md.digest());
				log.info("签名后的数据："+sign);
			return sign;
			} catch (NoSuchAlgorithmException e) {

				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {

				e.printStackTrace();
			}
			return null;
	  }
	
	  public static boolean  checkSign(String jsonData,String sign){
		  if(sign.equals(chinaumsSign(jsonData))){
			  return true;
		  } 
		  	return false;
	  }
	     
	  /**
	   * @date 2019年8月21日
	   * @author 若尘
	   * @Description 签名验证并解密
	   * @param resultStr
	   * @return
	   * JSONObject
	   */
		public static JSONObject  decryptAndcheckSign(String resultStr){
			JSONObject  result=JSONObject.parseObject(resultStr)  ;
			if(!"0000".equals(result.getString("res_code"))){
				throw new ApiException(resultStr);
			}
		        String accesser_id = result.getString("accesser_id");   //外部系统平台标识，由ums分配    
		        if(!accesserId.equals(accesser_id)){   log.error("系统平台标识与银联分配的不匹配。原值："+accesserId+"现值："+accesser_id); }
		        String json_data=result.getString("json_data");
		        //解密
		        String  jsonData=Chinaums3DesUtil.decrypt3DES(json_data);
		        //验签
		        if(  Chinaums3DesUtil.checkSign(jsonData,result.getString("sign_data"))==false){
		        	log.error("签名不正确！！！，元数据："+resultStr); 
		        	throw new ApiException("签名不正确");
		        }
		        return JSONObject.parseObject(jsonData);
		} 

	
}
